home *** CD-ROM | disk | FTP | other *** search
/ Reverse Code Engineering RCE CD +sandman 2000 / ReverseCodeEngineeringRceCdsandman2000.iso / RCE / Ebooks / Thinking in C++ V2 / C22 / Persist2.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2000-05-25  |  2.9 KB  |  124 lines

  1. //: C22:Persist2.cpp
  2. // From Thinking in C++, 2nd Edition
  3. // Available at http://www.BruceEckel.com
  4. // (c) Bruce Eckel 1999
  5. // Copyright notice in Copyright.txt
  6. // Improved MI persistence
  7. #include "../require.h"
  8. #include <iostream>
  9. #include <fstream>
  10. #include <cstring>
  11. using namespace std;
  12.  
  13. class Persistent {
  14. public:
  15.   virtual void write(ostream& out) const = 0;
  16.   virtual void read(istream& in) = 0;
  17.   virtual ~Persistent() {}
  18. };
  19.  
  20. class Data {
  21. protected:
  22.   float f[3];
  23. public:
  24.   Data(float f0 = 0.0, float f1 = 0.0,
  25.     float f2 = 0.0) {
  26.     f[0] = f0;
  27.     f[1] = f1;
  28.     f[2] = f2;
  29.   }
  30.   void print(const char* msg = "") const {
  31.     if(*msg) cout << msg << endl;
  32.     for(int i = 0; i < 3; i++)
  33.       cout << "f[" << i << "] = "
  34.            << f[i] << endl;
  35.   }
  36. };
  37.  
  38. class WData1 : public Persistent, public Data {
  39. public:
  40.   WData1(float f0 = 0.0, float f1 = 0.0,
  41.     float f2 = 0.0) : Data(f0, f1, f2) {}
  42.   void write(ostream& out) const {
  43.     out << f[0] << " " 
  44.       << f[1] << " " << f[2] << " ";
  45.   }
  46.   void read(istream& in) {
  47.     in >> f[0] >> f[1] >> f[2];
  48.   }
  49. };
  50.  
  51. class WData2 : public Data, public Persistent {
  52. public:
  53.   WData2(float f0 = 0.0, float f1 = 0.0,
  54.     float f2 = 0.0) : Data(f0, f1, f2) {}
  55.   void write(ostream& out) const {
  56.     out << f[0] << " " 
  57.       << f[1] << " " << f[2] << " ";
  58.   }
  59.   void read(istream& in) {
  60.     in >> f[0] >> f[1] >> f[2];
  61.   }
  62. };
  63.  
  64. class Conglomerate : public Data,
  65. public Persistent {
  66.   char* name; // Contains a pointer
  67.   WData1 d1;
  68.   WData2 d2;
  69. public:
  70.   Conglomerate(const char* nm = "",
  71.     float f0 = 0.0, float f1 = 0.0,
  72.     float f2 = 0.0, float f3 = 0.0,
  73.     float f4 = 0.0, float f5 = 0.0,
  74.     float f6 = 0.0, float f7 = 0.0,
  75.     float f8= 0.0) : Data(f0, f1, f2),
  76.     d1(f3, f4, f5), d2(f6, f7, f8) {
  77.     name = new char[strlen(nm) + 1];
  78.     strcpy(name, nm);
  79.   }
  80.   void write(ostream& out) const {
  81.     int i = strlen(name) + 1;
  82.     out << i << " "; // Store size of string
  83.     out << name << endl;
  84.     d1.write(out);
  85.     d2.write(out);
  86.     out << f[0] << " " << f[1] << " " << f[2];
  87.   }
  88.   // Must read in same order as write:
  89.   void read(istream& in) {
  90.     delete []name; // Remove old storage
  91.     int i;
  92.     in >> i >> ws; // Get int, strip whitespace
  93.     name = new char[i];
  94.     in.getline(name, i);
  95.     d1.read(in);
  96.     d2.read(in);
  97.     in >> f[0] >> f[1] >> f[2];
  98.   }
  99.   void print() const {
  100.     Data::print(name);
  101.     d1.print();
  102.     d2.print();
  103.   }
  104. };
  105.  
  106. int main() {
  107.   {
  108.     ofstream data("data.dat");
  109.     assure(data, "data.dat");
  110.     Conglomerate C("This is Conglomerate C",
  111.       1.1, 2.2, 3.3, 4.4, 5.5,
  112.       6.6, 7.7, 8.8, 9.9);
  113.     cout << "C before storage" << endl;
  114.     C.print();
  115.     C.write(data);
  116.   } // Closes file
  117.   ifstream data("data.dat");
  118.   assure(data, "data.dat");
  119.   Conglomerate C;
  120.   C.read(data);
  121.   cout << "after storage: " << endl;
  122.   C.print();
  123. } ///:~
  124.